﻿from django.shortcuts import render_to_response, get_object_or_404
from codemonkeys.codescratches.models import Scratch, Language
from django import newforms as forms
from django.http import HttpResponse, HttpResponseRedirect
from pygments import highlight
from pygments.formatters import HtmlFormatter, RawTokenFormatter
from pygments.lexers import get_lexer_by_name, DiffLexer, RawTokenLexer
from random import Random
from django.http import Http404
import string
#import difflib


#TODO: diff, export: RSS

def get_tuple_from_model(objs):
    return [(obj.id, obj.longname) for obj in objs]

class ScratchForm(forms.Form):
    parent_id = forms.IntegerField()
    code = forms.CharField(widget=forms.Textarea)
    lang = forms.IntegerField(widget=forms.Select(choices=get_tuple_from_model(Language.objects.all())))
    comment = forms.CharField(widget=forms.Textarea, required=False)
    is_private = forms.BooleanField()
    
    
def index(request):
    f = ScratchForm()
    return render_to_response('codescratches/index.html', {'scratch_form': f, 'parent_id' : 0})

def codemonkeys_index(request):
    return render_to_response('index.html')

def getScratch(scratch_id):
    try:
        s = Scratch.objects.get(pk=scratch_id)
        if s.private_key:
            raise Http404
        else:
            return s
    except Scratch.DoesNotExist:
        s = get_object_or_404(Scratch, private_key=scratch_id)
        return s


def details(request, scratch_id):
    s = getScratch(scratch_id)
    scratch_id = s.id
        
    rel_s = Scratch.objects.filter(parent_id = scratch_id)
    f = ScratchForm({'lang': s.language_id.id})
    return render_to_response('codescratches/details.html', {'scratch': s, 'rel_s': rel_s, 'scratch_form':f})


def exportAsHTML(request, scratch_id):
    s = getScratch(scratch_id)
    return render_to_response('codescratches/export.html', {'scratch': s})

def exportAsTXT(request, scratch_id):
    s = getScratch(scratch_id)
    return HttpResponse(s.code, mimetype="text/plain")

                
def addScratch(request):
    if request.method == 'POST': 
        form = ScratchForm(request.POST)
        if form.is_valid():
            parent_id = form.cleaned_data['parent_id']
            key = ''
            if parent_id:
                parent_scratch = Scratch.objects.get(pk = parent_id)
                if parent_scratch.private_key:
                    key = ''.join(Random().sample(string.letters+string.digits, 12))
            if form.cleaned_data['is_private']:
                key = ''.join(Random().sample(string.letters+string.digits, 12))
            l = Language.objects.get(id = form.cleaned_data['lang'])                            
            lexer = get_lexer_by_name(l.name, stripall=True)
            formatter = HtmlFormatter(linenos=True, cssclass="source")
            lj_formatter = HtmlFormatter(noclasses=True) 
            pr_code = highlight(form.cleaned_data['code'], lexer, formatter)       
            lj_code = highlight(form.cleaned_data['code'], lexer, lj_formatter)           
            s = Scratch(code = form.cleaned_data['code'], processed_code = pr_code, comment = form.cleaned_data['comment'],  language_id = l, parent_id = form.cleaned_data['parent_id'], lj_code= lj_code, private_key = key)
            s.save()
            if s.parent_id == 0:
                if key:
                    return HttpResponseRedirect('/publicode/view/%s' % key )
                else:
                    return HttpResponseRedirect('/publicode/view/%d' % s.id )

            else:
                if key:
                    return HttpResponseRedirect('/publicode/view/%s' % parent_scratch.private_key)
                else:
                    return HttpResponseRedirect('/publicode/view/%d' % s.parent_id )

        else:           
            if request.POST['parent_id'] > 0:
                pid = request.POST['parent_id']
            else:
                pid = 0
            return render_to_response('codescratches/index.html', {'scratch_form': form, 'parent_id' : pid})
    else:
        return HttpResponseRedirect('/publicode/')
